package com.net.xpay.common.service.impl;

import com.google.common.base.Preconditions;
import com.net.xpay.common.domain.stat.CompanyBillDailyStat;
import com.net.xpay.common.enums.config.CommonSysConfigKey;
import com.net.xpay.common.helper.CommonSysConfigHelper;
import com.net.xpay.common.manager.stat.CompanyBillDailyStatManager;
import com.net.common.util.LocalDateUtil;
import com.net.xpay.common.manager.partner.PartnerWithdrawRecordManager;
import com.net.xpay.common.service.CompanyBillDailyStatInnerService;
import com.net.xpay.common.service.CompanyBillDailyStatService;
import com.net.shard.ShardDataSource;
import com.net.shard.ShardDataSourceConfigurer;
import com.net.shard.ShardUtil;
import com.net.shard.domain.ShardConfig;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import javax.sql.DataSource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Map;

/**
 * 2020/9/22 17:00

 */
@Slf4j
@Service
public class CompanyBillDailyStatServiceImpl implements CompanyBillDailyStatService {

    @Autowired
    @Qualifier("shardDataSource")
    private DataSource shardDataSource;

    @Autowired
    private CompanyBillDailyStatInnerService companyBillDailyStatInnerService;

    @Autowired
    private CompanyBillDailyStatManager companyBillDailyStatManager;

    @Autowired
    private PartnerWithdrawRecordManager partnerWithdrawRecordManager;

    @Autowired
    private CommonSysConfigHelper commonSysConfigHelper;

    /**
     * 统计日账单
     *
     * @param day 日期
     * @return 日账单
     */
    @Override
    public CompanyBillDailyStat statDailyCompanyBill(LocalDate day) {
        ShardDataSourceConfigurer shardDataSourceConfigurer = ((ShardDataSource) shardDataSource).getShardDataSourceConfigurer();
        Map<Long, ShardConfig> shardConfigMap = shardDataSourceConfigurer.getShardConfigMap();
        Preconditions.checkArgument(CollectionUtils.isNotEmpty(shardConfigMap.keySet()));

        CompanyBillDailyStat stat = CompanyBillDailyStat.getInstance(day);

        //分库
        for (Long shardId : shardConfigMap.keySet()) {
            try {
                ShardUtil.setShardContext(shardId);
                log.info("statDailyCompanyBill start in shard={}|day={}", shardId, day);
                CompanyBillDailyStat shardStat = companyBillDailyStatInnerService.statDailyCompanyBill(day);
                addShardStat(stat, shardStat);
                log.info("statDailyCompanyBill end in shard={}|day={}", shardId, day);
            } finally {
                ShardUtil.cleanShardContext();
            }
        }
        //公共库
        //提现数据 根据当前时间获取改天的起始时间和结束时间
        LocalDateTime startTime = LocalDateUtil.getDayStart(day);
        LocalDateTime endTime = LocalDateUtil.getDayStart(day.plusDays(1L));
        long transferMoney = partnerWithdrawRecordManager.statTransferMoney(startTime, endTime);
        stat.setPartnerWithdrawAmount(transferMoney);

        /**
         * 成本预估
         */
        //到卡成本费率有调整 2024年2月6日之前的到卡费率是千1 2月6日以后是万5
        //预估充值手续费
        BigDecimal bankRatio = new BigDecimal(commonSysConfigHelper.getString(CommonSysConfigKey.SINGE_TRANS_BANK_COST_RATIO));
        BigDecimal estimateChargeCost = new BigDecimal(stat.getRechargeAmount()).multiply(new BigDecimal("0.01")).multiply(new BigDecimal("0.006")).setScale(2, RoundingMode.HALF_UP);
        BigDecimal estimateBankCost = stat.getSafePayTransSuccessBankAmount().multiply(bankRatio).setScale(2, RoundingMode.HALF_UP);
        stat.setEstimateChargeCost(estimateChargeCost);
        stat.setEstimateBankCost(estimateBankCost);

        companyBillDailyStatManager.save(stat);

        return stat;
    }

    //叠加分库数据
    private void addShardStat(CompanyBillDailyStat stat, CompanyBillDailyStat shardStat) {
        stat.setRechargeAmount(stat.getRechargeAmount() + shardStat.getRechargeAmount());
        stat.setReverseRechargeAmount(stat.getReverseRechargeAmount() + shardStat.getReverseRechargeAmount());
        stat.setSuccessServicePrice(stat.getSuccessServicePrice() + shardStat.getSuccessServicePrice());
        stat.setRealSuccessServicePrice(stat.getRealSuccessServicePrice() + shardStat.getRealSuccessServicePrice());
        stat.setTotalPartnerBenefit(stat.getTotalPartnerBenefit() + shardStat.getTotalPartnerBenefit());
        stat.setTotalFatherPartnerBenefit(stat.getTotalFatherPartnerBenefit() + shardStat.getTotalFatherPartnerBenefit());
        stat.setTotalPlatformBenefit(stat.getTotalPlatformBenefit() + shardStat.getTotalPlatformBenefit());
        stat.setUserWithdrawAmount(stat.getUserWithdrawAmount() + shardStat.getUserWithdrawAmount());
        stat.setSuccessAmount(stat.getSuccessAmount().add(shardStat.getSuccessAmount()));
        stat.setSuccessCount(stat.getSuccessCount() + shardStat.getSuccessCount());

        stat.setSafePaySuccessServicePrice(stat.getSafePaySuccessServicePrice() + shardStat.getSafePaySuccessServicePrice());
        stat.setSafePayTotalPartnerBenefit(stat.getSafePayTotalPartnerBenefit() + shardStat.getSafePayTotalPartnerBenefit());
        stat.setSafePayTotalFatherPartnerBenefit(stat.getSafePayTotalFatherPartnerBenefit() + shardStat.getSafePayTotalFatherPartnerBenefit());
        stat.setSafePayTotalPlatformBenefit(stat.getSafePayTotalPlatformBenefit() + shardStat.getSafePayTotalPlatformBenefit());
        stat.setSafePaySuccessAmount(stat.getSafePaySuccessAmount().add(shardStat.getSafePaySuccessAmount()));
        stat.setSafePaySuccessCount(stat.getSafePaySuccessCount() + shardStat.getSafePaySuccessCount());
        stat.setSafePayTransSuccessBankAmount(stat.getSafePayTransSuccessBankAmount().add(shardStat.getSafePayTransSuccessBankAmount()));
    }
}
